package com.ithanwen.utils;

/**
 * Created By tony
 * <br/>Date: 2025/8/13 11:51
 * <br/>Description:
 */

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;

import javax.crypto.SecretKey;
import java.util.Base64;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * JWT 工具类
 */
public class JwtUtils {

    // 默认密钥（生产环境应从配置读取）
    private static final String DEFAULT_SECRET = "aG94dXdvemhlbmRleWl3dXN1b3lvdW5pc2hpc2hlaXphaXdlaXNoZQ==";

    // 默认过期时间（1小时）
    private static final long DEFAULT_EXPIRATION = 3600 * 1000;

    // 转换为SecretKey
    private static final SecretKey SECRET_KEY = Keys.hmacShaKeyFor(Base64.getDecoder().decode(DEFAULT_SECRET));

    /**
     * 生成JWT Token
     * @param claims 自定义声明
     * @return JWT Token字符串
     */
    public static String generateToken(Map<String, Object> claims) {
        return generateToken(claims, DEFAULT_EXPIRATION);
    }

    /**
     * 生成JWT Token（自定义过期时间）
     * @param claims 自定义声明
     * @param expiration 过期时间（毫秒）
     * @return JWT Token字符串
     */
    public static String generateToken(Map<String, Object> claims, long expiration) {
        return Jwts.builder()
                .setClaims(claims)  // 设置自定义声明
                .setIssuedAt(new Date())  // 设置签发时间
                .setExpiration(new Date(System.currentTimeMillis() + expiration))  // 设置过期时间
                .signWith(SECRET_KEY, SignatureAlgorithm.HS256)  // 使用HS256算法和密钥签名
                .compact();
    }

    /**
     * 生成JWT Token（简化版）
     * @param username 用户名
     * @param userId 用户ID
     * @return JWT Token字符串
     */
    public static String generateToken(String username, String userId) {
        Map<String, Object> claims = new HashMap<>();
        claims.put("username", username);
        claims.put("id", userId);
        return generateToken(claims);
    }

    /**
     * 从Token中解析Claims
     * @param token JWT Token
     * @return Claims对象
     */
    public static Claims parseToken(String token) {
        return Jwts.parserBuilder()
                .setSigningKey(SECRET_KEY)
                .build()
                .parseClaimsJws(token)
                .getBody();
    }

    /**
     * 验证Token是否有效
     * @param token JWT Token
     * @return 是否有效
     */
    public static boolean validateToken(String token) {
        try {
            parseToken(token);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 从Token中获取指定声明
     * @param token JWT Token
     * @param claimName 声明名称
     * @return 声明值
     */
    public static Object getClaimFromToken(String token, String claimName) {
        Claims claims = parseToken(token);
        return claims.get(claimName);
    }

    /**
     * 从Token中获取用户名
     * @param token JWT Token
     * @return 用户名
     */
    public static String getUsernameFromToken(String token) {
        return (String) getClaimFromToken(token, "username");
    }

    /**
     * 从Token中获取用户ID
     * @param token JWT Token
     * @return 用户ID
     */
    public static String getUserIdFromToken(String token) {
        return (String) getClaimFromToken(token, "id");
    }

    /**
     * 检查Token是否过期
     * @param token JWT Token
     * @return 是否过期
     */
    public static boolean isTokenExpired(String token) {
        Claims claims = parseToken(token);
        return claims.getExpiration().before(new Date());
    }

    /**
     * 刷新Token（更新过期时间）
     * @param token 原Token
     * @param expiration 新的过期时间（毫秒）
     * @return 新Token
     */
    public static String refreshToken(String token, long expiration) {
        Claims claims = parseToken(token);
        claims.setIssuedAt(new Date());
        claims.setExpiration(new Date(System.currentTimeMillis() + expiration));
        return Jwts.builder()
                .setClaims(claims)
                .signWith(SECRET_KEY, SignatureAlgorithm.HS256)
                .compact();
    }
}